﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading;

namespace Loader
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(SomeExceptionHandler);
        }

        private string dir_source = @"\\fs\КОРПОРАТИВНЫЙ ФАЙЛОВЫЙ РЕСУРС\Ярлыки программ\Аналитическая система";

        private SqlConnection conn = new SqlConnection();

        static void SomeExceptionHandler(object sender, UnhandledExceptionEventArgs args)
        {
            Exception e = (Exception)args.ExceptionObject;
            MessageBox.Show(e.ToString());
            // TODO: Обработать исключение
        }

        private string GetServ(string filename)
        {
            string str = "";
            try
            {
                using (StreamReader streamReader = new StreamReader(filename))
                {
                    while (!streamReader.EndOfStream)
                    {
                        str += streamReader.ReadLine();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Метод Loader.GetServ(string filename)\n" + ex.ToString());
                str = "SDATA2";
            }
            return str;
        }

        private bool ExistConn(SqlConnection sqlcon)
        {
            try
            {
                sqlcon.Open();
                sqlcon.Close();
            }
            catch
            {
                MessageBox.Show("Соединение с сервером отсутсвует, обратитесь к разработчику");
                return false;
            }
            return true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
             //   Process[] AllProcesses = Process.GetProcessesByName("loader");
             //   if (AllProcesses.Length == 1)
                {
                    if (!File.Exists(@"serv.txt")) File.Copy(@"\\fs\КОРПОРАТИВНЫЙ ФАЙЛОВЫЙ РЕСУРС\Ярлыки программ\Аналитическая система\serv.txt", @"serv.txt");
                    conn.ConnectionString = @"Server= " + GetServ("serv.txt") + @";Database=SecurityFA;Integrated Security=True";
                    if (!checkBox1.Checked) button1_Click(sender, e);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Сервер неопределен \n" + ex.ToString());
            }
            finally
            {
                this.Close();
            }
        }

        private struct fileversion
        {
            public string filename;
            public string folder;
            public string version;
            public bool flag;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //AutoResetEvent autoEvent = new AutoResetEvent(false);
            //for (int i = 0; i < 5 && checkBox1.Checked; i++)
            //{
            //    autoEvent.WaitOne(1000);
            //}
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (ExistConn(conn))
                {
                    SqlCommand myCommand = conn.CreateCommand();
                    myCommand.CommandType = CommandType.StoredProcedure;
                    myCommand.CommandText = @"AllFalesForUserProc";
                    conn.Open();
                    SqlDataReader dataReader = myCommand.ExecuteReader();
                    fileversion[] fv = new fileversion[] { };
                    while (dataReader.Read())
                    {
                        if (string.Compare(dataReader.GetString(dataReader.GetOrdinal("FileName")), Path.GetFileName(Application.ExecutablePath), true) != 0)
                        {
                            Array.Resize(ref fv, fv.Length + 1);
                            fv[fv.Length - 1].filename = dataReader.GetString(dataReader.GetOrdinal("FileName"));
                            fv[fv.Length - 1].folder = dataReader.GetString(dataReader.GetOrdinal("Folder"));
                            fv[fv.Length - 1].version = dataReader.GetString(dataReader.GetOrdinal("Version"));
                        }
                    }
                    dataReader.Close();
                    conn.Close();

                    string dir = Directory.GetCurrentDirectory();
                    string[] files = Directory.GetFiles(dir, "*.dll", SearchOption.AllDirectories);
                    string[] exefiles = Directory.GetFiles(dir, "*.exe", SearchOption.AllDirectories);
                    string[] servtxt = Directory.GetFiles(dir, "serv.txt", SearchOption.AllDirectories);

                    fileversion[] fv_curr = new fileversion[files.Length];

                    for (int i = 0; i < files.Length; i++)
                    {
                        FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(files[i]);
                        fv_curr[i].version = myFileVersionInfo.FileVersion.ToString();
                        fv_curr[i].folder = Path.GetDirectoryName(files[i]).Replace(dir, @"");
                        fv_curr[i].filename = Path.GetFileName(files[i]);
                    }

                    Regex regex = new Regex(@"\.vshost\.");

                    for (int i = 0; i < exefiles.Length; i++)
                    {
                        if (string.Compare(Path.GetFileNameWithoutExtension(exefiles[i]), Path.GetFileNameWithoutExtension(Application.ExecutablePath), true) != 0)
                            if (!Regex.Match(exefiles[i], @"\.vshost\.", RegexOptions.IgnoreCase).Success)
                            {
                                Array.Resize(ref fv_curr, fv_curr.Length + 1);
                                FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(exefiles[i]);
                                fv_curr[fv_curr.Length - 1].version = myFileVersionInfo.FileVersion.ToString();
                                fv_curr[fv_curr.Length - 1].folder = Path.GetDirectoryName(exefiles[i]).Replace(dir, @"");
                                fv_curr[fv_curr.Length - 1].filename = Path.GetFileName(exefiles[i]);
                            }
                    }

                    for (int i = 0; i < servtxt.Length; i++)
                    {
                        Array.Resize(ref fv_curr, fv_curr.Length + 1);
                        fv_curr[fv_curr.Length - 1].version = "0.0.0.1";
                        fv_curr[fv_curr.Length - 1].folder = Path.GetDirectoryName(servtxt[i]).Replace(dir, @"");
                        fv_curr[fv_curr.Length - 1].filename = Path.GetFileName(servtxt[i]);
                    }

                    for (int j = 0; j < fv.Length; j++)
                    {
                        for (int k = 0; k < fv_curr.Length; k++)
                        {
                            if (!fv_curr[k].flag)
                            {
                                if (string.Compare(fv[j].filename, fv_curr[k].filename, true) == 0 && string.Compare(fv[j].folder, fv_curr[k].folder, true) == 0)
                                {
                                    if (string.Compare(fv[j].version, fv_curr[k].version, true) == 0)
                                    {
                                        fv[j].flag = true;
                                    }
                                    fv_curr[k].flag = true;
                                }
                            }
                        }
                    }

                    Array.Resize(ref files, 0);
                    files = Directory.GetFiles(dir_source, "*", SearchOption.AllDirectories);
                    fileversion[] fv_source = new fileversion[files.Length];
                    for (int i = 0; i < files.Length; i++)
                    {
                        FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(files[i]);
                        if (myFileVersionInfo.FileVersion != null) fv_source[i].version = myFileVersionInfo.FileVersion.ToString();
                        else fv_source[i].version = "0.0.0.0";
                        fv_source[i].filename = Path.GetFileName(files[i]);
                        fv_source[i].folder = Path.GetDirectoryName(files[i]).Replace(dir_source, @"");
                    }

                    for (int j = 0; j < fv.Length; j++)
                    {
                        if (!fv[j].flag)
                        {
                            bool fl = false;
                            for (int i = 0; i < fv_source.Length; i++)
                            {
                                if (string.Compare(fv_source[i].filename, fv[j].filename, true) == 0)
                                {
                                    if (string.Compare(fv_source[i].version, fv[j].version, true) == 0)
                                    {
                                        if (!Directory.Exists(dir + fv[j].folder)) Directory.CreateDirectory(dir + fv[j].folder);
                                        File.Copy(dir_source + @"\" + fv_source[i].filename, dir + fv[j].folder + @"\" + fv[j].filename, true);
                                        fv[j].flag = true;
                                        i = fv_source.Length;
                                    }
                                    else MessageBox.Show("Версия файла на сервере " + fv[j].filename + " не совпадает с актуальной версией");
                                    fl = true;
                                }
                            }
                            if (!fl) MessageBox.Show("На сервере обновлений отсутсвует файл " + fv[j].filename);
                        }
                    }

                    for (int k = 0; k < fv_curr.Length; k++)
                        if (!fv_curr[k].flag)
                        {
                            fv_curr[k].flag = false;
                            File.Delete(dir + fv_curr[k].folder + @"\" + fv_curr[k].filename);
                        }

                    string[] dirs = Directory.GetDirectories(dir, "*", SearchOption.AllDirectories);
                    for (int i = 0; i < dirs.Length; i++)
                        if (Directory.Exists(dirs[i]))
                            if (Directory.GetFiles((dirs[i]), "*", SearchOption.AllDirectories).Length == 0)
                                Directory.Delete(dirs[i], true);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка при загрузке обновлений\n" + ex.Message);
            }
            finally
            {
                string filename = @"MainForm.exe";
                if (File.Exists(filename)) Process.Start(filename, textBox1.Text);
                this.Close();
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked) textBox1.Enabled = true;
            else textBox1.Enabled = textBox1.Enabled = false;
        }
    }
}
